From: Colin Walters Date: Fri, 14 Aug 2009 08:34:28 +0000 (-0400) Subject: Add shell_app_system_create_from_window X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~11046 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=d94606587bf8fab284f1bfb2f26a07f30c09a525;p=gnome-shell.git Add shell_app_system_create_from_window For various cases such as when we don't know a .desktop file for a window, it's desirable to "fake" an application from the contents of a MetaWindow*. --- diff --git a/src/shell-app-system.c b/src/shell-app-system.c index d4ee4cbc6..05060c2de 100644 --- a/src/shell-app-system.c +++ b/src/shell-app-system.c @@ -57,7 +57,8 @@ G_DEFINE_TYPE(ShellAppSystem, shell_app_system, G_TYPE_OBJECT); typedef enum { SHELL_APP_INFO_TYPE_ENTRY, - SHELL_APP_INFO_TYPE_DESKTOP_FILE + SHELL_APP_INFO_TYPE_DESKTOP_FILE, + SHELL_APP_INFO_TYPE_WINDOW } ShellAppInfoType; struct _ShellAppInfo { @@ -75,6 +76,9 @@ struct _ShellAppInfo { GKeyFile *keyfile; char *keyfile_path; + + MetaWindow *window; + char *window_id; }; ShellAppInfo* @@ -97,6 +101,9 @@ shell_app_info_unref (ShellAppInfo *info) case SHELL_APP_INFO_TYPE_DESKTOP_FILE: g_key_file_free (info->keyfile); g_free (info->keyfile_path); + case SHELL_APP_INFO_TYPE_WINDOW: + g_object_unref (info->window); + g_free (info->window_id); break; } g_slice_free (ShellAppInfo, info); @@ -117,6 +124,23 @@ shell_app_info_new_from_tree_item (GMenuTreeItem *item) return info; } +static ShellAppInfo * +shell_app_info_new_from_window (MetaWindow *window) +{ + ShellAppInfo *info; + + info = g_slice_alloc (sizeof (ShellAppInfo)); + info->type = SHELL_APP_INFO_TYPE_WINDOW; + info->refcount = 1; + info->window = g_object_ref (window); + /* For windows, its id is simply its pointer address as a string. + * There are various other alternatives, but the address is unique + * and unchanging, which is pretty much the best we can do. + */ + info->window_id = g_strdup_printf ("window:%p", window); + return info; +} + static ShellAppInfo * shell_app_info_new_from_keyfile_take_ownership (GKeyFile *keyfile, const char *path) @@ -574,8 +598,6 @@ set_gconf_value_string_list (GConfValue *val, GList *items) g_slist_free (tmp); } - - void shell_app_system_add_favorite (ShellAppSystem *system, const char *id) { @@ -670,6 +692,21 @@ shell_app_system_load_from_desktop_file (ShellAppSystem *system, return appinfo; } +/** + * shell_app_system_create_from_window: + * + * In the case where we can't otherwise determine an application + * associated with a window, this function can create a "fake" + * application just backed by information from the window itself. + * + * Return value: (transfer full): A new #ShellAppInfo + */ +ShellAppInfo * +shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window) +{ + return shell_app_info_new_from_window (window); +} + /** * shell_app_system_lookup_heuristic_basename: * @name: Probable application identifier @@ -719,6 +756,8 @@ shell_app_info_get_id (ShellAppInfo *info) return gmenu_tree_entry_get_desktop_file_id ((GMenuTreeEntry*)info->entry); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: return info->keyfile_path; + case SHELL_APP_INFO_TYPE_WINDOW: + return info->window_id; } g_assert_not_reached (); return NULL; @@ -735,6 +774,12 @@ shell_app_info_get_name (ShellAppInfo *info) return g_strdup (gmenu_tree_entry_get_name ((GMenuTreeEntry*)info->entry)); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Name", NULL, NULL); + case SHELL_APP_INFO_TYPE_WINDOW: + { + char *title; + g_object_get (info->window, "title", &title, NULL); + return title; + } } g_assert_not_reached (); return NULL; @@ -749,6 +794,8 @@ shell_app_info_get_description (ShellAppInfo *info) return g_strdup (gmenu_tree_entry_get_comment ((GMenuTreeEntry*)info->entry)); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Comment", NULL, NULL); + case SHELL_APP_INFO_TYPE_WINDOW: + return NULL; } g_assert_not_reached (); return NULL; @@ -763,6 +810,8 @@ shell_app_info_get_executable (ShellAppInfo *info) return g_strdup (gmenu_tree_entry_get_exec ((GMenuTreeEntry*)info->entry)); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: return g_key_file_get_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Exec", NULL); + case SHELL_APP_INFO_TYPE_WINDOW: + return NULL; } g_assert_not_reached (); return NULL; @@ -776,45 +825,29 @@ shell_app_info_get_desktop_file_path (ShellAppInfo *info) case SHELL_APP_INFO_TYPE_ENTRY: return g_strdup (gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*)info->entry)); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: - return g_strdup (info->keyfile_path);; + return g_strdup (info->keyfile_path); + case SHELL_APP_INFO_TYPE_WINDOW: + return NULL; } g_assert_not_reached (); return NULL; } -GIcon * -shell_app_info_get_icon (ShellAppInfo *info) +static GIcon * +themed_icon_from_name (const char *iconname) { - char *iconname = NULL; GIcon *icon; - /* This code adapted from gdesktopappinfo.c - * Copyright (C) 2006-2007 Red Hat, Inc. - * Copyright © 2007 Ryan Lortie - * LGPL - */ - - switch (info->type) - { - case SHELL_APP_INFO_TYPE_ENTRY: - iconname = g_strdup (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry)); - break; - case SHELL_APP_INFO_TYPE_DESKTOP_FILE: - iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL); - break; - } - if (!iconname) - return NULL; + return NULL; if (g_path_is_absolute (iconname)) { GFile *file; - file = g_file_new_for_path (iconname); icon = G_ICON (g_file_icon_new (file)); g_object_unref (file); - } + } else { char *tmp_name, *p; @@ -827,15 +860,42 @@ shell_app_info_get_icon (ShellAppInfo *info) { *p = 0; } - icon = g_themed_icon_new (tmp_name); g_free (tmp_name); } - g_free (iconname); return icon; } +static GIcon * +shell_app_info_get_icon (ShellAppInfo *info) +{ + char *iconname = NULL; + GIcon *icon; + + /* This code adapted from gdesktopappinfo.c + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright © 2007 Ryan Lortie + * LGPL + */ + + switch (info->type) + { + case SHELL_APP_INFO_TYPE_ENTRY: + return themed_icon_from_name (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry)); + case SHELL_APP_INFO_TYPE_DESKTOP_FILE: + iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL); + icon = themed_icon_from_name (iconname); + g_free (iconname); + return icon; + break; + case SHELL_APP_INFO_TYPE_WINDOW: + return NULL; + } + g_assert_not_reached (); + return NULL; +} + GSList * shell_app_info_get_categories (ShellAppInfo *info) { @@ -850,12 +910,26 @@ shell_app_info_get_is_nodisplay (ShellAppInfo *info) case SHELL_APP_INFO_TYPE_ENTRY: return gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry*)info->entry); case SHELL_APP_INFO_TYPE_DESKTOP_FILE: + case SHELL_APP_INFO_TYPE_WINDOW: return FALSE; } g_assert_not_reached (); return TRUE; } +/** + * shell_app_info_is_transient: + * + * A "transient" application is one which represents + * just an open window, i.e. we don't know how to launch it + * again. + */ +gboolean +shell_app_info_is_transient (ShellAppInfo *info) +{ + return info->type == SHELL_APP_INFO_TYPE_WINDOW; +} + /** * shell_app_info_create_icon_texture: * @@ -870,6 +944,13 @@ shell_app_info_create_icon_texture (ShellAppInfo *info, float size) GIcon *icon; ClutterActor *ret; + if (info->type == SHELL_APP_INFO_TYPE_WINDOW) + { + return shell_texture_cache_bind_pixbuf_property (shell_texture_cache_get_default (), + G_OBJECT (info->window), + "icon"); + } + icon = shell_app_info_get_icon (info); if (!icon) { @@ -908,6 +989,17 @@ shell_app_info_launch_full (ShellAppInfo *info, if (startup_id) *startup_id = NULL; + if (info->type == SHELL_APP_INFO_TYPE_WINDOW) + { + /* We can't pass URIs into a window; shouldn't hit this + * code path. If we do, fix the caller to disallow it. + */ + g_return_val_if_fail (uris == NULL, TRUE); + + meta_window_activate (info->window, timestamp); + return TRUE; + } + filename = shell_app_info_get_desktop_file_path (info); gapp = g_desktop_app_info_new_from_filename (filename); g_free (filename); diff --git a/src/shell-app-system.h b/src/shell-app-system.h index 7691eafaf..b8d20f9c9 100644 --- a/src/shell-app-system.h +++ b/src/shell-app-system.h @@ -4,6 +4,8 @@ #include #include +#include "window.h" + #define SHELL_TYPE_APP_SYSTEM (shell_app_system_get_type ()) #define SHELL_APP_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_APP_SYSTEM, ShellAppSystem)) #define SHELL_APP_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_APP_SYSTEM, ShellAppSystemClass)) @@ -58,10 +60,10 @@ char *shell_app_info_get_name (ShellAppInfo *info); char *shell_app_info_get_description (ShellAppInfo *info); char *shell_app_info_get_executable (ShellAppInfo *info); char *shell_app_info_get_desktop_file_path (ShellAppInfo *info); -GIcon *shell_app_info_get_icon (ShellAppInfo *info); ClutterActor *shell_app_info_create_icon_texture (ShellAppInfo *info, float size); GSList *shell_app_info_get_categories (ShellAppInfo *info); gboolean shell_app_info_get_is_nodisplay (ShellAppInfo *info); +gboolean shell_app_info_is_transient (ShellAppInfo *info); gboolean shell_app_info_launch_full (ShellAppInfo *info, guint timestamp, GList *uris, @@ -77,6 +79,8 @@ ShellAppInfo *shell_app_system_lookup_cached_app (ShellAppSystem *system, const ShellAppInfo *shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, const char *id); +ShellAppInfo *shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window); + GSList *shell_app_system_get_menus (ShellAppSystem *system); GSList *shell_app_system_get_all_settings (ShellAppSystem *system);